<?php 
namespace Core\Application;

use Core\Debugger\AlertLevel;
use Core\Debugger\LogEntry;
use \Core\Debugger\Logger;

use Library\IO\Directory;


/**
 * Provides methods for the modules management. This class cannot be inherits.
 * @namespace Core\Application
 * @author Raphael DE FREITAS (RaphyTheGeek@gmail.com)
 * @version 1.0
 * 
 */
final class Modules
{
	protected $_Modules = array();
	
	protected static $_Instance = null;
	
	private function __construct() {
		
	}
	
	public static function getInstance() {
		if(is_null(self::$_Instance))
			self::$_Instance = new Modules;
		return self::$_Instance;
	}

	public function loadModules() {
		Logger::log(new LogEntry('Loading modules...'));
		$this->_Modules = array();
		foreach(Directory::getDirectories(ROOT.'modules') as $module_name) {
			$this->_Modules[$module_name] = new Module($module_name);
		}
		$this->checkIndependencies();
		$this->addRoutesAndConfig();
		Logger::log(new LogEntry('There are '.count($this->_Modules).' modules !'));
	}
	
	protected function checkIndependencies() {
		Logger::log(new LogEntry('Checking independencies ...'));
		foreach($this->_Modules as $module) {
			if(!$module->hasDependenciesFile())
				continue;
			
			Logger::log(new LogEntry('Reading dependencies file '.str_replace(ROOT, './', $module->getDependenciesFile()).'...'));
			$xml = new \DOMDocument;
			$xml->load($module->getDependenciesFile());
			$independencies = $xml->getElementsByTagName('dependent');
			foreach($independencies as $independent) {
				if ($independent->hasAttribute('module')) {
					if(!array_key_exists($independent->getAttribute('module'), $this->_Modules)) {
						Logger::log(new LogEntry('The module "'.$module->getName().'" requires "'.$independent->getAttribute('module').'" module.', AlertLevel::Warning));
						unset($this->_Modules[$module->getName()]);
					}
				}
			}
		}
	}
	
	protected function addRoutesAndConfig() {
		Logger::log(new LogEntry('Applying routes & configs for the modules...'));
		foreach($this->_Modules as $module) {
			if($module->hasRoutesFile())
				Router::getInstance()->addFromFile($module->getRoutesFile());
			if($module->hasConfigurationFile())
				Configuration::getInstance()->addFromFile($module->getConfigurationFile());
		}
	}
	
	public function getModules() {
		return $this->_Modules;
	}
	
	public function getModule($name) {
		return $this->_Modules[$name];
	}
}
?>